Before a manufacturer installs an operating system on a computer system, typically it tests and verifies the operation of both the hardware and firmware.
Pre-Operating System Environments—For many computer systems with Intel central processing units, the pre-operating system verification environment is the extensible firmware interface (EFI). The EFI environment is typically used with verification tools to test interactions between chipsets, system busses, I/O busses, peripherals, system firmware and other system level entities. EFI is an industry standard and applies to all IPF systems. Specifically, the EFI firmware interfaces with the System Abstraction Layer (SAL), which in turn interfaces with the Processor Abstraction Layer (PAL), which interfaces with a hardware IPF processor.
The EFI environment manages a computer system's memory until an operating system is booted. Pre-operating system verification applications can be run both inside of EFI (EFI applications) and on top of EFI (non-EFI applications) as part of the EFI environment utilizing the EFI library of functions such as the real time clock and tables of EFI parameters and variable names. The EFI library is also accessible by the operating system after it is booted.
Compilation—Computers typically execute low-level machine languages that are easily processed by computer processors but that are difficult and time consuming for programmers to use, whereas programming is typically done in a high level language that is easier and less time consuming for programmers to use. A compiler is a translator whose source language is a high-level language and whose object language is close to the machine language of an actual computer, either being an assembly language or some variety of machine language (relocatable or absolute). Translation of a high-level source language into executable machine language programs often involves more than one translation step. For example, it is not uncommon to have a program first compiled into a machine-dependent assembly language, then assembled to produce relocatable machine code, and finally loaded and linked to produce executable machine code. Moreover, the compilation step itself typically involves a number of passes that progressively translate the program into various intermediate forms before producing the final object program.
Loaders—A loader, or linking loader, is a translator step whose object language is the actual executable machine code, and whose source language is almost identical, but usually consists of machine language programs in relocatable form together with tables of data specifying points where the relocatable code must be modified to become truly executable. This step is performed just prior to execution after actual memory has been allocated.
Libraries—A scope is typically classified as dynamic or static. A dynamic scope rule defines a scope in terms of program execution at run time. A static scope rule defines a scope in terms of the structure of the program at build time (translation time). Programs typically contain function calls to modules in a library that is available to the compiler. In a static library environment, the modules referenced by the program function calls are linked and loaded at build time and cannot be changed at run time. In a dynamic environment, the library is available at run time and the linking and loading of the library modules is done just prior to initialization of execution.
References—Referencing is the operation of retrieving the data or program object currently associated with a given identifier using the unique currently active association for the identifier. References to identifiers are classified as local references if they use an association active only within the subprogram currently being executed. A global reference is a reference to an association active throughout program execution. A local environment or local referencing environment is used to designate those local associations introduced at the last change in the referencing environment.
The above-described concepts are discussed and illustrated below in conjunction with FIGS. 1A-3.
Referring to FIG. 1A, a static pre-operating system build time environment 10 is shown that includes an EFI application 2 and a non-EFI application 4, both of which include function calls to EFI library module 8. The library module 8 is in the form of relocatable machine code with a table of data specifying points where the relocatable code must be modified to become truly executable machine code. The static pre-operating system build time environment 10 includes a static loader 6. During the final step of the compilation of the application 2, the static loader 6 links a first copy of the module 8 to the application 2 and modifies all of the places where a relative address needs to be replaced with an absolute address. In a similar manner, during the final step of the compilation of the non-EFI application 4, the static loader 6 links a second copy of the module 8 to the application 4 and modifies all of the places where a relative address needs to be replaced with an absolute address. In such a static pre-operating system build time environment, each function call in each application 2 and 4 requires a copy of the relocatable library module 8. Any change to the source code in the applications 2 and 4 or the called module 8 requires a complete recompilation of the applications.
Referring to FIG. 1B, the static pre-operating system run time environment 12 associated with the static pre-operating build environment 10 (FIG. 1A) no longer has access to a loader. The compiled EFI application 2 linked to the compiled EFI library module 8 is in non-relocatable machine code format and is loaded into memory to be executed.
FIG. 1C shows the static pre-operating system run time environment 12 associated with the static pre-operating build environment 10 during execution. The compiled application 2 contains function calls 14 which are satisfied by the compiled and linked copy of EFI module 8. The variables inside of the library module 8 with global references have access to all the variables associated with the compiled application 2. The reference environment is static and is set at build time and cannot be changed without a recompilation. Also, if there is any change in the code for application 2 the entire package needs to be recompiled, and if there is any change in the code for module 8, the entire package needs to be recompiled. Therefore, if there is any additional required functionality, the functionality has to be added in a static pre-operating build environment and the entire package needs to be recompiled.
Referring to FIG. 2A, a static pre-operating system build time environment 20 includes of a number (here four) of applications AA-DD, some of which are EFI applications and some of which are non-EFI applications, and all of which require functionality from EFI library module NN. The static loader 6 copies module NN into each of the applications, links the relocatable machine code of the module NN to the machine code of the applications AA-DD, and produces four applications in absolute machine code format capable of being executed.
Referring to FIG. 2B, the static pre-operating system run time environment 22 associated with the static pre-operating build environment 20 (FIG. 2A) no longer has access to a loader. The absolute binaries of applications AA-DD can be executed. There can be no changes to the applications or the shared library module without recompiling. Also, there is no way to add or remove functionality to or from any of the applications AA-DD without a complete recompilation of the entire set.
Referring to FIG. 3, a pre-operating system environment upgrade process 112 includes a static build time environment 112, a static run time environment 114, and an upgrade environment 120. As previously described, during static build time 110, EFI applications 100 and non-EFI applications 104 are compiled using the EFI library 102 to satisfy function call references. This is done by the static loader 106 copying modules from the EFI library 102 into the applications and linking them in an absolute machine code format. During the static run time 114, the compiled EFI application 116 with linked library modules is executed. During the static run time 114, the compiled non-EFI application 118 with linked library modules is also executed. If there is a code upgrade 122 to an EFI application or a non-EFI application during an upgrade time 120, the process returns to the build time environment 110 via the path 124 and recompiles the applications. If there is a code upgrade to a referenced library module the process returns to the build time environment 110 via the path 124 and recompiles the applications after recompiling the EFI library 106 with the upgraded module. There is no means to change the static environments without starting the process over from the beginning. This is inconvenient, costly, procedurally complex, inflexible, and time intensive.